#include "config.h"
#include "log.h"
#include <yaml-cpp/yaml.h>
#include <algorithm>
#include <sstream>
#include <memory>
namespace sylar
{
    ConfigVarBase::ptr Config::LookupBase(std::string &name)
    {
        
        RWMutexType::ReadLock rlock(GetMutex());
        auto ptr = GetDatas().find(name);
        if (ptr == GetDatas().end())
        {
            return nullptr;
        }
        return ptr->second;
    }
    // 完善后的 ListAllMember（含 root 空/Null 检查）

    static void ListAllMember(const std::string &prefix,
                              const YAML::Node &node,
                              std::list<std::pair<std::string, const YAML::Node>> &output)
    {
        if (prefix.find_first_not_of("abcdefghikjlmnopqrstuvwxyz._012345678") != std::string::npos)
        {
            SYLAR_LOG_ERROR(SYLAR_ERROR_LOGGER()) << "Config invalid name: " << prefix << " : " << node;
            return;
        }
        output.push_back(std::make_pair(prefix, node));
        if (node.IsMap())
        {
            for (auto it = node.begin();
                 it != node.end(); ++it)
            {
                ListAllMember(prefix.empty() ? it->first.Scalar()
                                             : prefix + "." + it->first.Scalar(),
                              it->second, output);
            }
        }
    }

    // 配套的 LoadFromYaml（加根节点检查）
    void Config::LoadFromYaml(const YAML::Node &root)
    {
        std::list<std::pair<std::string, const YAML::Node>> all_nodes;
        ListAllMember("", root, all_nodes);

        for (auto &i : all_nodes)
        {
            std::string key = i.first;
            if (key.empty())
            {
                continue;
            }

            std::transform(key.begin(), key.end(), key.begin(), ::tolower);
            ConfigVarBase::ptr var = LookupBase(key);

            if (var)
            {
                if (i.second.IsScalar())
                {
                    var->fromString(i.second.Scalar());
                }
                else
                {
                    std::stringstream ss;
                    ss << i.second;
                    var->fromString(ss.str());
                }
            }
        }
        std::cout << "LoadYaml OK \n";
    }
    void Config::Visit(std::function<void(ConfigVarBase::ptr)>cb)
    {
        RWMutexType::ReadLock rlock(GetMutex());
        ConfigVarMap& m =GetDatas();
        for(auto it=m.begin();it!=m.end();++it)
        {
            cb(it->second);
        }
    }

} // namespace sylar